package com.startx.core.netty.pipeline;

import java.io.InputStream;
import java.security.KeyStore;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;

import com.startx.core.config.holder.ConfigHolder;
import com.startx.core.netty.handler.WebsocketHandler;
import com.startx.core.system.config.StartxConfig;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;

public class WebsocketPipeline extends ChannelInitializer<SocketChannel> {

	private static final int READ_IDEL_TIME_OUT = 3; // 读超时
	private static final int WRITE_IDEL_TIME_OUT = 4;// 写超时
	private static final int ALL_IDEL_TIME_OUT = 5; // 所有超时
	
	@Override
	protected void initChannel(SocketChannel ch) throws Exception {

		ChannelPipeline pipeline = ch.pipeline();
		
		StartxConfig config = ConfigHolder.getConfig();
		if(config.isSSL()) {
			KeyStore ks = KeyStore.getInstance("JKS");
			InputStream ksInputStream = HttpPipeline.class.getResourceAsStream(config.getJksPath());
			ks.load(ksInputStream, config.getJksPwd().toCharArray());
			KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
			kmf.init(ks,config.getJksPwd().toCharArray());
			SSLContext sslCtx = SSLContext.getInstance("TLS");
			sslCtx.init(kmf.getKeyManagers(), null, null);
			
			SSLEngine engine = sslCtx.createSSLEngine();
    		engine.setUseClientMode(false);
    		engine.setNeedClientAuth(false);
    		pipeline.addLast("ssl",new SslHandler(engine));
		}
		
		pipeline.addLast(new IdleStateHandler(READ_IDEL_TIME_OUT,WRITE_IDEL_TIME_OUT, ALL_IDEL_TIME_OUT, TimeUnit.MINUTES));
    	pipeline.addLast("http-codec", new HttpServerCodec());
    	pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
    	pipeline.addLast("http-chunked", new ChunkedWriteHandler());
    	pipeline.addLast("handler",new WebsocketHandler());
	}

}
